home *** CD-ROM | disk | FTP | other *** search
- /* Controller.m --- Main controller object for the TextLab program.
- ** Authors: Bruce Blumberg and Ali Ozer, NeXT Developer Support Group
- ** 8-14-90 Converted to 2.0 by Randy Nelson, NeXT Developer Training
- ** Changed internal strings to external using NXStringTable
- ** Removed outlet initializers
- ** Removed 0.9 reference to Font Manager
- ** 9-7-90 Changed new method to use init, externally stored info panel
- **
- ** You may freely copy, distribute and reuse the code in this example.
- ** NeXT disclaims any warranty of any kind, expressed or implied, as to
- ** its fitness for any particular use.
- */
-
- // Controller object is the central object in TextLab. It manages the
- // windows, open/save panels, and menu commands.
-
- #import "Controller.h"
- #import "TextView.h"
- #import <appkit/Application.h>
- #import <objc/typedstream.h>
- #import <objc/NXStringTable.h>
- #import <appkit/FontManager.h>
- #import <appkit/Font.h>
-
- @implementation Controller
-
- - init
- {
- [super init];
-
- // get instances of support objects
- openReq = [OpenPanel new];
- saveReq = [SavePanel new];
- [self make2Windows];
- return self;
- }
-
-
- - infoPanel:sender
- {
- if (infoPanel == nil) {
- [NXApp loadNibSection:"Info.nib" owner:self];
- }
- [infoPanel orderFront:sender];
- return self;
- }
-
- - showError: (const char *)errorMessage
- {
- NXRunAlertPanel(NULL, errorMessage,
- [stringSet valueForStringKey:"OK"], NULL, NULL);
- return self;
- }
-
- // newTextView: is invoked in response to a new empty window request. It
- // creates a new window containing a TextView. Note that we want new windows
- // to be offset from each other by some amount; hence the use of wRect.
-
- #define ORIGX 0.0
- #define ORIGY 0.0
- // static NXRect wRect = {{ORIGX, ORIGY},{450.0,400.0}};
- static NXRect sourceRect = {{120.0, 440.0},{800.0,300.0}};
- static NXRect diagramRect = {{120.0, 100.0},{800.0,300.0}};
-
- - make2Windows
- {
- id diagramText;
- id sourceText;
-
- // diagramView = [self newTextView:self];
- diagramView = [[TextView alloc] initFrame:&diagramRect];
- // [[diagramView window] setDelegate:self];
- [[diagramView window] setTitle:"Diagram"];// replace "Untitled"
- diagramText = [diagramView docView];
- [diagramText setFont:[Font newFont:"IBMKlone" size:12.0 ]];
-
- [diagramText setDescentLine:0.0];
- [diagramText setLineHeight:36.0];
- [diagramText calcLine];
-
- // sourceView = [self newTextView:self];
- sourceView = [[TextView alloc] initFrame:&sourceRect];
- [[sourceView window] setDelegate:self];
- [[sourceView window] setTitle:"SourceCode"]; // replace "Untitled"
-
- sourceText = [sourceView docView];
- [sourceText selectText:self];
- [sourceText setDelegate:self]; // so we will get textDidGetKeys msg.
-
- return self;
- }
-
- - newTextView:sender
- {
- //int i (int i); /*counter*/
- id newTextView;
- NXOffsetRect(&sourceRect, 100.0, 100.0);
- if (sourceRect.origin.y < 0) {
- sourceRect.origin.y = ORIGY;
- sourceRect.origin.x = ORIGX;
- }
- //for (i=1; i++);
- newTextView = [[TextView alloc] initFrame:&sourceRect];
- [[newTextView window] setDelegate:self];
- [[newTextView window] setTitle:"SourceCode"/*,++i*/]; // replace "Untitled"
- // return self;
- return newTextView;
- }
-
- // appAcceptsAnotherFile is an application delegate method which
- // returns whether it is OK for the application to try to open more files
- // with the appOpenFile:type: method. TextLab can indeed open multiple
- // windows, so we return YES.
-
- -(BOOL) appAcceptsAnotherFile:sender
- {
- return (YES);
- }
-
-
- // appOpenFile:type: is called to open the specified file. It is normally
- // called by the Application object in response to open requests from the
- // Workspace. Here we also route the open requests from the OpenPanel
- // to this method (see openRequest:).
-
- -(int) appOpenFile:(char *)fileName type:(char *)fileType
- {
- return [self openFile:fileName];
- }
-
- // openRequest: opens a new file. It puts up a open panel, and, if the user
- // doesn't cancel, it reads the specified archive file. If the selected file
- // is not a proper archive file, then openRequest: will complain.
-
- - openRequest:sender
- {
- const char *fileName;
- const char *const types[] = {[stringSet valueForStringKey:"extension"],
- "tl", NULL};
-
- if ([openReq runModalForTypes:types] && (fileName = [openReq filename])) {
- [self openFile:fileName];
- }
- else
- [self showError:[stringSet valueForStringKey:"errorOnOpenRequest"]];
- return self;
- }
-
- -(int) openFile:(const char *)fileName
- {
- id win;
- NXTypedStream *typedStream;
-
- if(!(typedStream = NXOpenTypedStreamForFile(fileName,NX_READONLY))){
- [self showError:[stringSet valueForStringKey:"errorOnOpen"]];
- return NO;
- }
- else {
- win = NXReadObject(typedStream);
- NXCloseTypedStream(typedStream);
- [win setTitle:fileName];
- [win setDelegate:self];
- // [[win display] makeKeyAndOrderFront:self];
- [win display];
- [win makeKeyAndOrderFront:self];
- [self windowDidBecomeKey:win]; // don't know why, but need this
- // to get delegate notification
- [self saveRequest:self];
- return YES;
- }
- }
-
-
- // saveRequest: saves the current window under its default name (found in
- // the title bar). Note that if the title bar is empty or the default title
- // is "SourceCode" then saveRequest: will put up a save panel, giving the user
- // a chance to specify a real title.
-
- - saveRequest:sender
- {
- const char *fileName;
- const char *const types[2] = {[stringSet valueForStringKey:"extension"],
- NULL};
-
- id curWin = [NXApp mainWindow];
- [saveReq setRequiredFileType:types[0]];
-
- if (curWin == nil)
- [self showError:[stringSet valueForStringKey:"errorOnSaveRequest"]];
- else {
- // Check to see if the current window is titled and the title is not
- // "Untitled". If so, save the file, else put up a save panel...
- fileName = [curWin title];
-
- printf("setString returns: %s\n", [stringSet valueForStringKey:"SourceCode"]);
- printf("setString returns: %s\n", [stringSet valueForStringKey:"Diagram"]);
-
- if (strcmp (fileName, [stringSet valueForStringKey:"Diagram"])) {
- if (strcmp (fileName, [stringSet valueForStringKey:"SourceCode"]))
- [self saveWindow:curWin inPath:fileName];
- else
- [self saveInRequest:sender];
- }
- else
- [self showError:[stringSet valueForStringKey:"errorOnDiagramSave"]];
- }
- [curWin setDocEdited:NO];
- return self;
- }
-
- // saveInRequest: gives the user a chance to save the current window
- // under a new name.
-
- - saveInRequest:sender
- {
- const char *fileName;
- const char *const types[2] = {[stringSet valueForStringKey:"extension"],
- NULL};
- id curWin;
-
- curWin = [NXApp mainWindow];
- [saveReq setRequiredFileType:types[0]];
-
- if (curWin == nil)
- [self showError:[stringSet valueForStringKey:"errorOnSaveIn"]];
- else {
- fileName = [curWin title];
- if (strcmp (fileName, [stringSet valueForStringKey:"Diagram"])){
- // Get a file name from the user; use title of the window as default.
- if (([saveReq runModalForDirectory:[stringSet valueForStringKey:"dot"]
- file:[curWin title]]) &&
- (fileName = [saveReq filename]))
- [self saveWindow:curWin inPath:fileName];}
- else {
- [self showError:[stringSet valueForStringKey:"errorOnDiagramSave"]];
- }
- }
- [curWin setDocEdited:NO];
- return self;
- }
-
-
- // saveWindow writes a window out the archive file whose name is specified
- // by the second argument. The title of the current window is also set
- // accordingly.
-
- - saveWindow:(id)win inPath:(const char *)name
- {
- NXTypedStream *typedStream;
-
- [win setTitle:name];
- typedStream = NXOpenTypedStreamForFile(name,NX_WRITEONLY);
- NXWriteRootObject(typedStream,win);
- NXCloseTypedStream(typedStream);
- return self;
- }
-
- // Printing is rather simple; just send printPSCode: to the text view
- // you wish to print. The print panel will automatically pop up and unless
- // the user cancels the printout the text view will be printed.
-
- - printRequest:sender
- {
- id curText = [[[NXApp mainWindow] contentView] docView];
-
- if (curText == nil) [self showError:[stringSet
- valueForStringKey:"errorOnPrintRequest"]];
- else {
- [[[NXApp printInfo] setHorizCentered:NO] setVertCentered:NO];
- [curText printPSCode:self];
- }
- return self;
- }
-
- // closeRequest closes the current window by simulating a click on the
- // closebutton. A check should probably be added to give the user the
- // option of saving the window before closing
-
- - closeRequest:sender
- {
- id curWin = [NXApp mainWindow];
-
- if ([curWin isDocEdited])
- [self saveRequest:self];
- else
- [[NXApp mainWindow] performClose:sender];
- return self;
- }
-
- -showActionDiagram:sender
- {
- [self writeSourceToTmp];
- // [theDiagrammer formatDiagram];
- system("adroff -g tmpAdroffSource tmpAdroffDiagram");
- [self readDiagToWindow2];
- return self;
- }
-
- -writeSourceToTmp
- {
- NXStream *stream;
- id sourceText;
- const char *fileName = "tmpAdroffSource";
-
- system("cp /dev/null tmpAdroffSource");
- sourceText = [sourceView docView];
- stream = NXMapFile(fileName, NX_WRITEONLY);
- NXSeek(stream,0, NX_FROMSTART);
- [sourceText writeText:stream];
- NXFlush(stream);
- NXSaveToFile(stream,fileName);
- NXCloseMemory(stream,NX_FREEBUFFER);
- return self;
- }
-
- - readDiagToWindow2
- {
- NXStream *stream;
- id diagText;
-
- const char *fileName = "tmpAdroffDiagram";
-
- diagText = [diagramView docView];
- stream = NXMapFile(fileName, NX_READONLY);
- NXSeek(stream,0, NX_FROMSTART);
- [diagText readText:stream];
- // NXFlush(stream);
- // NXSaveToFile(stream,fileName);
- NXCloseMemory(stream,NX_FREEBUFFER);
- return self;
- }
-
- /*
- * Delegate method for the document Text object. We use this method
- * to detect when the text in the window is modified.
- */
- - textDidGetKeys:textObject isEmpty:(BOOL)flag
- {
- id curWin = [NXApp mainWindow];
- // id curWin = [NXApp keyWindow];
- // if (![[sourceView window] isDocEdited])
- if (![curWin isDocEdited])
- {
- [curWin setDocEdited:YES];
- }
- return NO;
- }
-
- - windowDidBecomeKey:sender
- {
- id sourceText;
- sourceView = [sender contentView];
- sourceText = [[sourceView docView] setDelegate:self];
- // [sourceText setSel:(int)0 :(int)0];
- [sender becomeMainWindow];
- return self;
- }
-
- // Called just before the window closes.
- - windowWillClose:sender
- {
- id curWin = [NXApp mainWindow];
-
- if ([curWin isDocEdited]){
- [self saveRequest:self];
- }
- return self;
- }
-
- @end
-